home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / ICMPHDR.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-29  |  2.5 KB  |  111 lines

  1. /* ICMP header conversion routines
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. #include "global.h"
  5. #include "mbuf.h"
  6. #include "internet.h"
  7. #include "ip.h"
  8. #include "icmp.h"
  9.  
  10. #if !defined(_lint)
  11. static char rcsid[] OPTIONAL = "$Id: icmphdr.c,v 1.7 1996/08/29 12:11:16 root Exp root $";
  12. #endif
  13.  
  14.  
  15. /* Generate ICMP header in network byte order, link data, compute checksum */
  16. struct mbuf *
  17. htonicmp (icmp, data)
  18. struct icmp *icmp;
  19. struct mbuf *data;
  20. {
  21. struct mbuf *bp;
  22. register unsigned char *cp;
  23. int16 thechecksum;
  24.  
  25.     if ((bp = pushdown (data, ICMPLEN)) == NULLBUF)
  26.         return NULLBUF;
  27.     cp = bp->data;
  28.  
  29.     *cp++ = uchar(icmp->type);
  30.     *cp++ = uchar(icmp->code);
  31.     cp = put16 (cp, 0);    /* Clear checksum */
  32.     switch (icmp->type) {
  33.         case ICMP_DEST_UNREACH:
  34.             if (icmp->code == ICMP_FRAG_NEEDED) {
  35.                 /* Deering/Mogul max MTU indication */
  36.                 cp = put16 (cp, 0);
  37.                 cp = put16 (cp, icmp->args.mtu);
  38.             } else
  39.                 cp = put32 (cp, 0L);
  40.             break;
  41.         case ICMP_PARAM_PROB:
  42.             *cp++ = icmp->args.pointer;
  43.             *cp++ = 0;
  44.             cp = put16 (cp, 0);
  45.             break;
  46.         case ICMP_REDIRECT:
  47.             cp = put32 (cp, icmp->args.address);
  48.             break;
  49.         case ICMP_ECHO:
  50.         case ICMP_ECHO_REPLY:
  51.         case ICMP_TIMESTAMP:
  52.         case ICMP_TIME_REPLY:
  53.         case ICMP_INFO_RQST:
  54.         case ICMP_INFO_REPLY:
  55.             cp = put16 (cp, icmp->args.echo.id);
  56.             cp = put16 (cp, icmp->args.echo.seq);
  57.             break;
  58.         default:
  59.             cp = put32 (cp, 0L);
  60.             break;
  61.     }
  62.     /* Compute checksum, and stash result */
  63.     thechecksum = cksum (NULLHEADER, bp, len_p (bp));
  64.     cp = &bp->data[2];
  65.     cp = put16 (cp, thechecksum);
  66.  
  67.     return bp;
  68. }
  69.  
  70.  
  71. /* Pull off ICMP header */
  72. int
  73. ntohicmp (icmp, bpp)
  74. struct icmp *icmp;
  75. struct mbuf **bpp;
  76. {
  77. char icmpbuf[8];
  78.  
  79.     if (icmp == (struct icmp *) NULL)
  80.         return -1;
  81.     if (pullup (bpp, (unsigned char *) icmpbuf, 8) != 8)
  82.         return -1;
  83.     icmp->type = icmpbuf[0];
  84.     icmp->code = icmpbuf[1];
  85.     switch (icmp->type) {
  86.         case ICMP_DEST_UNREACH:
  87.             /* Retrieve Deering/Mogul MTU value */
  88.             if (icmp->code == ICMP_FRAG_NEEDED)
  89.                 icmp->args.mtu = get16 (&icmpbuf[6]);
  90.             break;
  91.         case ICMP_PARAM_PROB:
  92.             icmp->args.pointer = uchar (icmpbuf[4]);
  93.             break;
  94.         case ICMP_REDIRECT:
  95.             icmp->args.address = get32 (&icmpbuf[4]);
  96.             break;
  97.         case ICMP_ECHO:
  98.         case ICMP_ECHO_REPLY:
  99.         case ICMP_TIMESTAMP:
  100.         case ICMP_TIME_REPLY:
  101.         case ICMP_INFO_RQST:
  102.         case ICMP_INFO_REPLY:
  103.             icmp->args.echo.id = get16 (&icmpbuf[4]);
  104.             icmp->args.echo.seq = get16 (&icmpbuf[6]);
  105.             break;
  106.         default:
  107.             break;
  108.     }
  109.     return 0;
  110. }
  111.